﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace WinKeyBoard.Helpers
{
    #region 段落，节点名
    /// <summary>
    /// 段落，节点名
    /// </summary>
    public enum Sections
    {
        /// <summary>
        /// 用户
        /// </summary>
        User,
        /// <summary>
        /// 系统版本
        /// </summary>
        SystemVersion,
        /// <summary>
        /// 主题
        /// </summary>
        Theme,
        /// <summary>
        /// 开机自启
        /// </summary>
        AutoStart,
        /// <summary>
        /// 启动后是否停靠边缘
        /// </summary>
        StartDock,
        /// <summary>
        /// 最小化
        /// </summary>
        Minimized,
        /// <summary>
        /// 下次关闭时，不再提醒我
        /// </summary>
        CloseWarn,
        /// <summary>
        /// 隐藏头部
        /// </summary>
        HideHeader,
    }
    #endregion

    #region 节点里面的Key键名
    /// <summary>
    /// 节点里面的Key键名
    /// </summary>
    public enum IniKeys
    {
        //User
        Account,
        Password,
        UserName,
        Email,
        RememberPwd,
        AutoLogin,

    }
    #endregion

    #region 文件名
    /// <summary>
    /// 文件名
    /// </summary>
    public enum FileNames
    {
        /// <summary>
        /// 用户
        /// </summary>
        UserSoft,
        /// <summary>
        /// 系统参数
        /// </summary>
        SystemSoft,
    }
    #endregion

    /// <summary>
    /// .ini文件类
    /// </summary>
    public class IniHelper
    {
        #region DllImport 单元
        /// <summary>
        /// 获取值
        /// </summary>
        /// <param name="section">段落名</param>
        /// <param name="key">键名</param>
        /// <param name="defval">读取异常是的缺省值</param>
        /// <param name="retval">键名所对应的的值，没有找到返回空值</param>
        /// <param name="size">返回值允许的大小</param>
        /// <param name="filepath">ini文件的完整路径</param>
        /// <returns></returns>
        [DllImport("kernel32.dll")]
        private static extern int GetPrivateProfileString(string section, string key, string defval, StringBuilder retval, int size, string filepath);

        /// <summary>
        /// 写入
        /// </summary>
        /// <param name="section">需要写入的段落名</param>
        /// <param name="key">需要写入的键名</param>
        /// <param name="val">写入值</param>
        /// <param name="filepath">ini文件的完整路径</param>
        /// <returns></returns>
        [DllImport("kernel32.dll")]
        private static extern int WritePrivateProfileString(string section, string key, string val, string filepath);
        #endregion


        /// <summary>
        /// 默认文件路径
        /// </summary>
        private static readonly string DefaultPath = AppDomain.CurrentDomain.BaseDirectory;
        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="section">节：段落名</param>
        /// <param name="key">键名</param>
        /// <param name="defValue">没有找到时返回的默认值</param>
        /// <param name="fileName">文件名（不带后缀名），默认为：softwareInfo</param>
        /// <returns></returns>
        public static string Read(Sections sections, IniKeys keys, string defValue = "", FileNames fileNames = FileNames.UserSoft)
        {
            return Read(sections.ToString(), keys.ToString(), defValue, fileNames.ToString());
        }
        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="section">节：段落名</param>
        /// <param name="key">键名</param>
        /// <param name="defValue">没有找到时返回的默认值</param>
        /// <param name="fileName">文件名（不带后缀名），默认为：softwareInfo</param>
        /// <returns></returns>
        public static string Read(string section, string key, string defValue = "", string fileName = "UserSoft")
        {
            string path = DefaultPath + $@"{fileName}.ini";
            StringBuilder sb = new StringBuilder(1024);
            GetPrivateProfileString(section, key, defValue, sb, 1024, path);
            return sb.ToString();
        }

        /// <summary>
        /// 写入数据
        /// </summary>
        /// <param name="section">节：段落名</param>
        /// <param name="key">键名</param>
        /// <param name="value">写入值</param>
        /// <param name="fileName">文件名（不带后缀名），默认为Info</param>
        public static void Write(Sections sections, IniKeys keys, object value, FileNames fileNames = FileNames.UserSoft)
        {
            Write(sections.ToString(), keys.ToString(), value, fileNames.ToString());
        }
        /// <summary>
        /// 写入数据
        /// </summary>
        /// <param name="section">节：段落名</param>
        /// <param name="key">键名</param>
        /// <param name="value">写入值</param>
        /// <param name="fileName">文件名（不带后缀名），默认为Info</param>
        public static void Write(string section, string key, object value, string fileName = "UserSoft")
        {
            string path = DefaultPath + $@"{fileName}.ini";
            WritePrivateProfileString(section, key, value.ToString(), path);
        }


        /// <summary>
        /// 写入节点的备注（键名默认为note）
        /// </summary>
        /// <param name="section">节：段落名</param>
        /// <param name="value">写入note的描述</param>
        /// <param name="fileName">文件名（不带后缀名），默认为Info</param>
        public static void WriteNote(string section, object value, string fileName = "UserSoft")
        {
            string path = DefaultPath + $@"{fileName}.ini";
            WritePrivateProfileString(section, "note", value.ToString(), path);
        }
        /// <summary>
        ///  写入节点的备注（键名默认为note）
        /// </summary>
        /// <param name="section">节：段落名</param>
        /// <param name="value">写入note的描述</param>
        /// <param name="fileName">文件名（不带后缀名），默认为Info</param>
        public static void WriteNote(Sections sections, object value, FileNames fileNames = FileNames.UserSoft)
        {
            string path = DefaultPath + $@"{fileNames}.ini";
            WritePrivateProfileString(sections.ToString(), "note", value.ToString(), path);
        }

        /// <summary>
        /// 读取节点的 value 值
        /// </summary>
        /// <param name="section">节：段落名</param>
        /// <param name="fileName">文件名（不带后缀名），默认为：softwareInfo</param>
        /// <returns>没有找到就返回空</returns>
        public static string ReadValue(string section, string fileName = "UserSoft")
        {
            string path = DefaultPath + $@"{fileName}.ini";
            StringBuilder sb = new StringBuilder(1024);
            GetPrivateProfileString(section, "value", "", sb, 1024, path);
            return sb.ToString();
        }
        /// <summary>
        /// 读取节点的 value 值
        /// </summary>
        /// <param name="section">节：段落名</param>
        /// <param name="fileName">文件名（不带后缀名），默认为：softwareInfo</param>
        /// <returns>没有找到就返回空</returns>
        public static string ReadValue(Sections sections, FileNames fileNames = FileNames.UserSoft)
        {
            string path = DefaultPath + $@"{fileNames}.ini";
            StringBuilder sb = new StringBuilder(1024);
            GetPrivateProfileString(sections.ToString(), "value", "", sb, 1024, path);
            return sb.ToString();
        }

        /// <summary>
        /// 写入节点的 value 值（键名默认为value）
        /// </summary>
        /// <param name="section">节：段落名</param>
        /// <param name="value">写入值</param>
        /// <param name="fileName">文件名（不带后缀名），默认为Info</param>
        public static void WriteValue(string section, object value, string fileName = "UserSoft")
        {
            string path = DefaultPath + $@"{fileName}.ini";
            WritePrivateProfileString(section, "value", value.ToString(), path);
        }
        /// <summary>
        /// 写入节点的 value 值（键名默认为value）
        /// </summary>
        /// <param name="section">节：段落名</param>
        /// <param name="value">写入值</param>
        /// <param name="fileName">文件名（不带后缀名），默认为Info</param>
        public static void WriteValue(Sections sections, object value, FileNames fileNames = FileNames.UserSoft)
        {
            string path = DefaultPath + $@"{fileNames}.ini";
            WritePrivateProfileString(sections.ToString(), "value", value.ToString(), path);
        }
        /// <summary>
        /// 同时写入 Value 和 Note
        /// </summary>
        /// <param name="sections">节点</param>
        /// <param name="Value">写入默认值</param>
        /// <param name="Note">写入描述</param>
        /// <param name="fileNames">文件名</param>
        public static void WriteValueNote(Sections sections, object Value, object Note, FileNames fileNames = FileNames.UserSoft)
        {
            string path = DefaultPath + $@"{fileNames}.ini";
            WritePrivateProfileString(sections.ToString(), "note", Note.ToString(), path);
            WritePrivateProfileString(sections.ToString(), "value", Value.ToString(), path);
        }


        /// <summary>
        /// 读取值，如果为空，则会写入默认描述和值
        /// </summary>
        /// <param name="section">节点名</param>
        /// <param name="writeDefaultValue">写入默认值</param>
        /// <param name="writeDefaultNote">写入默认描述</param>
        /// <param name="fileName">写入默认描述</param>
        /// <returns>返回读取或写入的值</returns>
        public static string ReadOrWrite(string section, string writeDefaultValue = "", string writeDefaultNote = "", string fileName = "softwareInfo")
        {
            string value = Read(section, "value", "", fileName);
            if (string.IsNullOrWhiteSpace(value))
            {
                Write(section, "note", writeDefaultNote, fileName);
                Write(section, "value", writeDefaultValue, fileName);
                value = Read(section, "value", writeDefaultValue, fileName);
            }
            return value;
        }

        /// <summary>
        /// 读取值，如果为空，则会写入默认描述和值
        /// </summary>
        /// <param name="section">节点名</param>
        /// <param name="writeDefaultValue">写入默认值</param>
        /// <param name="writeDefaultNote">写入默认描述</param>
        /// <param name="fileName">写入默认描述</param>
        /// <returns>返回读取或写入的值</returns>
        public static string ReadOrWrite(Sections sections, string writeDefaultValue = "", string writeDefaultNote = "", FileNames fileName = FileNames.UserSoft)
        {
            return ReadOrWrite(sections.ToString(), writeDefaultValue, writeDefaultNote, fileName.ToString());
        }

    }
}
